with ada.text_io;

procedure assg1 is

    subtype buffer is String (Integer range 1..256);

    package t_io renames ada.text_io;

    function decode (to_decode : Character; key : Character) return Character is
	keyOffset, charOffset : Natural;
    begin
	keyOffset := Character'pos (key) - Character'pos ('A');
	charOffset := (Character'pos (to_decode) - Character'pos ('a') + keyOffset) mod 26;
	t_io.put(to_decode);
	t_io.put(" pos: " & integer'image (Character'pos(to_decode)) & ", using key ");
	t_io.put(key);
	t_io.put(" giving an offset of " & integer'image(keyOffset));
	t_io.new_line;
	return Character'val (Character'pos('a') +` charOffset);
    end decode;

    key, filename : buffer;
    key_length : Natural;
    key_index : Natural;
    file_length : Natural;
    in_f, out_f : t_io.File_Type;
    c : Character;

begin

    t_io.put("Enter the Key to decode with  > ");
    t_io.get_line (key, key_length);

    t_io.put("Enter the name of the input file  > ");
    t_io.get_line (filename, file_length);
    t_io.open(in_f, t_io.In_File, filename(1..file_length));

    t_io.put("Enter the name of the output file  > ");
    t_io.get_line (filename, file_length);
    begin
	t_io.open(out_f, t_io.Out_file, filename(1..file_length));
    exception
	when t_io.name_error =>
	    t_io.create(out_f, t_io.Out_file, filename);
    end;

    key_index := 0;
    loop
	t_io.get(in_f, c);
	if Character'pos(c) >= Character'pos('A') and Character'pos(c) <= Character'pos ('z') then
	    c := decode(c, key(key_index+1));
	end if;
	if c /= ' ' then
	    key_index := (key_index + 1) mod (key_length);
	end if;
	t_io.put(out_f, c);
	if t_io.end_of_line(in_f) then
	    t_io.new_line(out_f);
	end if;
	exit when t_io.end_of_file(in_f);
    end loop;

    t_io.put_line ("operations completed");
end assg1;
